home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / comm / bbs / s342q16.lha / compact.c < prev    next >
C/C++ Source or Header  |  1996-08-29  |  8KB  |  707 lines

  1. /*
  2. *                compact.c
  3. *
  4. * message compaction / encryption
  5. */
  6. #include "ctdl.h"
  7. /*
  8. *                history
  9. *
  10. * 89Jun05 HAW  Created.
  11. */
  12. /*
  13. *                Contents
  14. *
  15. *    StartEncode()        Start baudot-v encoding.
  16. *    StopEncode()        Stop same.
  17. *    Encode()        Does actual encoding of a byte.
  18. *    Combine()        Work function for encoding.
  19. *    StartDecode()        Start Decoding.
  20. *    StopDecode()        Stop Decoding.
  21. *    Decode()        Actual decoding function.
  22. *    Decode2()        Work function.
  23. */
  24. /* #define DEBUG */
  25. void StopEncode(void);
  26. static int Combine(int val);
  27. static int Decode2(int val);
  28. #define NO_SET        4    /* no such set */
  29. #define CAPS        0
  30. #define SPEC_CHARS    3
  31. #define COMP_SPACE    26    /* universal */
  32. #define ZERO_COMP    16
  33. #define RET_COMP    17
  34. static struct
  35.   {
  36.   char Set,           /* code set */
  37.   CompValue;     /* position in code set */
  38.   
  39.   }
  40. compress[] =
  41.   {
  42.     {
  43.     0, 0
  44.     
  45.     }
  46.   ,
  47.     {
  48.     2, 10
  49.     
  50.     }
  51.   ,
  52.     {
  53.     2, 11
  54.     
  55.     }
  56.   ,
  57.     {
  58.     2, 12
  59.     
  60.     }
  61.   ,
  62.     {
  63.     2, 13
  64.     
  65.     }
  66.   , /* ' ' - '$' */
  67.     {
  68.     2, 14
  69.     
  70.     }
  71.   ,
  72.     {
  73.     2, 15
  74.     
  75.     }
  76.   ,
  77.     {
  78.     2, 16
  79.     
  80.     }
  81.   ,
  82.     {
  83.     2, 17
  84.     
  85.     }
  86.   ,
  87.     {
  88.     2, 18
  89.     
  90.     }
  91.   , /* '%' - ')' */
  92.     {
  93.     2, 19
  94.     
  95.     }
  96.   ,
  97.     {
  98.     2, 20
  99.     
  100.     }
  101.   ,
  102.     {
  103.     2, 21
  104.     
  105.     }
  106.   ,
  107.     {
  108.     2, 22
  109.     
  110.     }
  111.   ,
  112.     {
  113.     2, 23
  114.     
  115.     }
  116.   , /* '*' - '.' */
  117.     {
  118.     2, 24
  119.     
  120.     }
  121.   ,
  122.     {
  123.     2, 0
  124.     
  125.     }
  126.   ,
  127.     {
  128.     2, 1
  129.     
  130.     }
  131.   ,
  132.     {
  133.     2, 2
  134.     
  135.     }
  136.   ,
  137.     {
  138.     2, 3
  139.     
  140.     }
  141.   ,  /* '/' - '3' */
  142.     {
  143.     2, 4
  144.     
  145.     }
  146.   ,
  147.     {
  148.     2, 5
  149.     
  150.     }
  151.   ,
  152.     {
  153.     2, 6
  154.     
  155.     }
  156.   ,
  157.     {
  158.     2, 7
  159.     
  160.     }
  161.   ,
  162.     {
  163.     2, 8
  164.     
  165.     }
  166.   ,  /* '4' - '8' */
  167.     {
  168.     2, 9
  169.     
  170.     }
  171.   ,
  172.     {
  173.     2, 25
  174.     
  175.     }
  176.   ,
  177.     {
  178.     3, 0
  179.     
  180.     }
  181.   ,
  182.     {
  183.     3, 1
  184.     
  185.     }
  186.   ,
  187.     {
  188.     3, 2
  189.     
  190.     }
  191.   ,  /* '9' - '=' */
  192.     {
  193.     3, 3
  194.     
  195.     }
  196.   ,
  197.     {
  198.     3, 4
  199.     
  200.     }
  201.   ,
  202.     {
  203.     3, 5
  204.     
  205.     }
  206.   ,
  207.     {
  208.     0, 0
  209.     
  210.     }
  211.   ,
  212.     {
  213.     0, 1
  214.     
  215.     }
  216.   ,  /* '>' - 'B' */
  217.     {
  218.     0, 2
  219.     
  220.     }
  221.   ,
  222.     {
  223.     0, 3
  224.     
  225.     }
  226.   ,
  227.     {
  228.     0, 4
  229.     
  230.     }
  231.   ,
  232.     {
  233.     0, 5
  234.     
  235.     }
  236.   ,
  237.     {
  238.     0, 6
  239.     
  240.     }
  241.   ,  /* 'C' - 'G' */
  242.     {
  243.     0, 7
  244.     
  245.     }
  246.   ,
  247.     {
  248.     0, 8
  249.     
  250.     }
  251.   ,
  252.     {
  253.     0, 9
  254.     
  255.     }
  256.   ,
  257.     {
  258.     0, 10
  259.     
  260.     }
  261.   ,
  262.     {
  263.     0, 11
  264.     
  265.     }
  266.   , /* 'H' - 'L' */
  267.     {
  268.     0, 12
  269.     
  270.     }
  271.   ,
  272.     {
  273.     0, 13
  274.     
  275.     }
  276.   ,
  277.     {
  278.     0, 14
  279.     
  280.     }
  281.   ,
  282.     {
  283.     0, 15
  284.     
  285.     }
  286.   ,
  287.     {
  288.     0, 16
  289.     
  290.     }
  291.   , /* 'M' - 'Q' */
  292.     {
  293.     0, 17
  294.     
  295.     }
  296.   ,
  297.     {
  298.     0, 18
  299.     
  300.     }
  301.   ,
  302.     {
  303.     0, 19
  304.     
  305.     }
  306.   ,
  307.     {
  308.     0, 20
  309.     
  310.     }
  311.   ,
  312.     {
  313.     0, 21
  314.     
  315.     }
  316.   , /* 'R' - 'V' */
  317.     {
  318.     0, 22
  319.     
  320.     }
  321.   ,
  322.     {
  323.     0, 23
  324.     
  325.     }
  326.   ,
  327.     {
  328.     0, 24
  329.     
  330.     }
  331.   ,
  332.     {
  333.     0, 25
  334.     
  335.     }
  336.   ,
  337.     {
  338.     3, 6
  339.     
  340.     }
  341.   ,  /* 'W' - '[' */
  342.     {
  343.     3, 7
  344.     
  345.     }
  346.   ,
  347.     {
  348.     3, 8
  349.     
  350.     }
  351.   ,
  352.     {
  353.     3, 9
  354.     
  355.     }
  356.   ,
  357.     {
  358.     3, 10
  359.     
  360.     }
  361.   ,
  362.     {
  363.     3, 11
  364.     
  365.     }
  366.   , /* '\' - '`' */
  367.     {
  368.     1, 0
  369.     
  370.     }
  371.   ,
  372.     {
  373.     1, 1
  374.     
  375.     }
  376.   ,
  377.     {
  378.     1, 2
  379.     
  380.     }
  381.   ,
  382.     {
  383.     1, 3
  384.     
  385.     }
  386.   ,
  387.     {
  388.     1, 4
  389.     
  390.     }
  391.   ,  /* 'a' - 'e' */
  392.     {
  393.     1, 5
  394.     
  395.     }
  396.   ,
  397.     {
  398.     1, 6
  399.     
  400.     }
  401.   ,
  402.     {
  403.     1, 7
  404.     
  405.     }
  406.   ,
  407.     {
  408.     1, 8
  409.     
  410.     }
  411.   ,
  412.     {
  413.     1, 9
  414.     
  415.     }
  416.   ,  /* 'f' - 'i' */
  417.     {
  418.     1, 10
  419.     
  420.     }
  421.   ,
  422.     {
  423.     1, 11
  424.     
  425.     }
  426.   ,
  427.     {
  428.     1, 12
  429.     
  430.     }
  431.   ,
  432.     {
  433.     1, 13
  434.     
  435.     }
  436.   ,
  437.     {
  438.     1, 14
  439.     
  440.     }
  441.   , /* 'j' - 'o' */
  442.     {
  443.     1, 15
  444.     
  445.     }
  446.   ,
  447.     {
  448.     1, 16
  449.     
  450.     }
  451.   ,
  452.     {
  453.     1, 17
  454.     
  455.     }
  456.   ,
  457.     {
  458.     1, 18
  459.     
  460.     }
  461.   ,
  462.     {
  463.     1, 19
  464.     
  465.     }
  466.   , /* 'p' - 't' */
  467.     {
  468.     1, 20
  469.     
  470.     }
  471.   ,
  472.     {
  473.     1, 21
  474.     
  475.     }
  476.   ,
  477.     {
  478.     1, 22
  479.     
  480.     }
  481.   ,
  482.     {
  483.     1, 23
  484.     
  485.     }
  486.   ,
  487.     {
  488.     1, 24
  489.     
  490.     }
  491.   , /* 'u' - 'y' */
  492.     {
  493.     1, 25
  494.     
  495.     }
  496.   ,
  497.     {
  498.     3, 12
  499.     
  500.     }
  501.   ,
  502.     {
  503.     3, 13
  504.     
  505.     }
  506.   ,
  507.     {
  508.     3, 14
  509.     
  510.     }
  511.   ,
  512.     {
  513.     3, 15
  514.     
  515.     }
  516.   /* 'z' - '~' */
  517.   
  518.   };
  519. static char EncCurSet;
  520. static int  BitsUsed, SendVal, Next, EncodeByteCount;
  521. int (*EncOF)(int c);
  522. int StartEncode(int (*func)(int c))
  523.   {
  524.   BitsUsed = 0;
  525.   EncCurSet   = NO_SET;
  526.   EncOF    = func;
  527.   SendVal  = 0;
  528.   EncodeByteCount = 0;
  529.   return 1;
  530.   
  531.   }
  532. void StopEncode()
  533.   {
  534.   if (EncodeByteCount == 0) return;    /* don't bother */
  535.   Combine(31);
  536.   Combine(0);
  537.   Combine(0);
  538.   Combine(0);
  539.   
  540.   }
  541. int Encode(int c)
  542.   {
  543.   int toReturn = TRUE;
  544.   EncodeByteCount++;
  545.   switch (c)
  546.     {
  547.     case ' ':   /* space exists in all code sets */
  548.     if (EncCurSet == NO_SET)
  549.       {
  550.       Combine(CAPS + 27);
  551.       EncCurSet = CAPS;
  552.       
  553.       }
  554.     toReturn = Combine(COMP_SPACE); break;
  555.     case 0:
  556.     case '\r':
  557.     if (EncCurSet != SPEC_CHARS)
  558.       {
  559.       Combine(SPEC_CHARS + 27);
  560.       EncCurSet = SPEC_CHARS;
  561.       
  562.       }
  563.     toReturn = Combine((c == 0) ? ZERO_COMP : RET_COMP);
  564.     break;
  565.     default:
  566.     /* discard if not printable, C/R, or 0 byte */
  567.     if (c >= ' ' && c < '~')
  568.       {
  569.       if (compress[c - 32].Set != EncCurSet)
  570.         {
  571.         Combine(compress[c - 32].Set + 27);
  572.         EncCurSet = compress[c - 32].Set;
  573.         
  574.         }
  575.       toReturn = Combine(compress[c - 32].CompValue);
  576.       
  577.       }
  578.     
  579.     }
  580.   return toReturn;
  581.   
  582.   }
  583. static int Combine(int val)
  584.   {
  585.   int        toReturn;
  586.   SendVal |= (val << BitsUsed);
  587.   SendVal &= 0xff;
  588.   Next = (val >> BitsUsed);
  589.   BitsUsed += 5;
  590.   if (BitsUsed >= 8)
  591.     {
  592.     toReturn = (*EncOF)(SendVal);
  593.     SendVal = val >> (13 - BitsUsed);
  594.     BitsUsed %= 8;
  595.     
  596.     }
  597.   else toReturn = TRUE;
  598.   return toReturn;
  599.   
  600.   }
  601. void StopDecode(void);
  602. #define NO_CAPS        1
  603. #define NUMERICS    2
  604. #define FINISHED    4    /* finished with encoded data */
  605. #define INIT_SET    5    /* an initial value */
  606. static char Numerics[] =
  607.   {
  608.   '0', '1', '2', '3', '4',
  609.   '5', '6', '7', '8', '9',
  610.   '!', '\"', '#', '$', '%',
  611.   '&', '\'', '(', ')', '*',
  612.   '+', ',', '-', '.', '/',
  613.   ':'
  614.   
  615.   };
  616. static char SpecChars[] =
  617.   {
  618.   ';', '<' , '=', '>', '?', '@', '[', '\\',
  619.   ']', 0x5e, '_', '`', '{', '|', '}', '~', 0,'\r'
  620.   
  621.   };
  622. static char DecCurSet;
  623. static int  ThisVal, NB;
  624. int (*DecOF)(int val);
  625. int StartDecode(int (*func)())
  626.   {
  627.   ThisVal = 0;
  628.   DecCurSet  = INIT_SET;
  629.   DecOF   = func;
  630.   NB      = 5;
  631.   return 1;
  632.   
  633.   }
  634. void StopDecode()
  635.   {
  636.   
  637.   }
  638. int Decode(int c)
  639.   {
  640.   static int mask[] =
  641.     {
  642.     0, 1, 3, 7, 0xf, 0x1f
  643.     
  644.     };
  645.   int AB;
  646.   if (DecCurSet == FINISHED) return TRUE;
  647.   if (!Decode2(c & mask[NB])) return FALSE;
  648.   c  >>= NB;
  649.   AB = 8 - NB;
  650.   if (AB >= 5)
  651.     {
  652.     ThisVal = 0;
  653.     AB -= 5;
  654.     NB  = 5;
  655.     if (!Decode2(c & mask[NB])) return FALSE;
  656.     c >>= 5;
  657.     
  658.     }
  659.   NB = 5 - AB;
  660.   ThisVal = c;
  661.   return TRUE;
  662.   
  663.   }
  664. static int Decode2(int val)
  665.   {
  666.   int toReturn;
  667.   char Used;
  668.   if (DecCurSet == FINISHED) return TRUE;
  669.   ThisVal += (val << (5 - NB));
  670.   switch (ThisVal - 27)
  671.     {
  672.     case CAPS:
  673.     case NO_CAPS:
  674.     case NUMERICS:
  675.     case SPEC_CHARS:
  676.     case FINISHED:
  677.     DecCurSet = ThisVal - 27;
  678.     Used = TRUE;
  679.     toReturn = TRUE;
  680.     break;
  681.     default: Used = FALSE;
  682.     
  683.     }
  684.   /* Discard if no set defined. */
  685.   if (!Used)
  686.     {
  687.     if (DecCurSet == INIT_SET) toReturn = TRUE;
  688.     /* True for any valid code set */
  689.     else if (ThisVal == COMP_SPACE) toReturn = (*DecOF)(' ');
  690.     else switch (DecCurSet)
  691.       {
  692.       case CAPS:
  693.       toReturn = (*DecOF)('A' + ThisVal); break;
  694.       case NO_CAPS:
  695.       toReturn = (*DecOF)('a' + ThisVal); break;
  696.       case NUMERICS:
  697.       toReturn = (*DecOF)(Numerics[ThisVal]); break;
  698.       case SPEC_CHARS:
  699.       toReturn = (*DecOF)(SpecChars[ThisVal]); break;
  700.       
  701.       }
  702.     
  703.     }
  704.   return toReturn;
  705.   
  706.   }
  707.